package javacroft.facade;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javacroft.business.*;

/** 
 * Classe manager de vue
 * @author Fabien RETIF
 * @version 1.0
 */
public class ViewManager
{  

   /**
    * Fonction qui retourne les départements en chaînes de caractères
    * @param lesDepartements : Liste des départements à mettre en chaînes de caractères
    * @return Liste de chaînes de caractères correspondant au nom de chaque département
    */
    public List<String> getLesDepartements(List<Departement> lesDepartements)
    {
        List<String> lesResultats = new ArrayList<String>();

        Iterator iter = lesDepartements.iterator();

        while (iter.hasNext())
        {
            lesResultats.add(((Departement)iter.next()).getNom());
        }

        return lesResultats;
    }

   /**
    * Fonction qui retourne les années en chaînes de caractères
    * @param lesAnnees  : Liste des années à mettre en chaînes de caractères
    * @return Liste de chaînes de caractères correspondant au nom de chaque année
    */
    public List<String> getLesAnnees(List<Annee> lesAnnees)
    {
        List<String> lesResultats = new ArrayList<String>();

        Iterator iter = lesAnnees.iterator();

        while (iter.hasNext())
        {
            lesResultats.add(((Annee)iter.next()).getNom());
        }

        return lesResultats;
    }

   /**
    * Fonction qui retourne les semestres en chaînes de caractères
    * @param lesSemestre : Liste des semestres à mettre en chaînes de caractères
    * @return Liste de chaînes de caractères correspondant au numéro de chaque semestre
    */
   public List<String> getLesSemestres(List<Semestre> lesSemestre)
   {
        List<String> lesResultats = new ArrayList<String>();

        Iterator iter = lesSemestre.iterator();

        while (iter.hasNext())
        {
            lesResultats.add(Integer.toString(((Semestre)iter.next()).getNumero()));
        }

        return lesResultats;
    }

   /**
    * Fonction qui retourne les UE en chaînes de caractères
    * @param lesUE  : Liste des UE à mettre en chaînes de caractères
    * @return Liste de chaînes de caractères correspondant au nom de chaque ue
    */
    public List<String> getLesUE(List<UE> lesUE)
    {
        List<String> lesResultats = new ArrayList<String>();

        Iterator iter = lesUE.iterator();

        while (iter.hasNext())
        {
            lesResultats.add(((UE)iter.next()).getNom());
        }

        return lesResultats;
    }

    /**
    * Fonction qui retourne les ECUE en chaînes de caractères
    * @param lesECUE : Liste des ECUE à mettre en chaînes de caractères
    * @return Liste de chaînes de caractères correspondant au nom de chaque ECUE
    */
    public List<String> getLesECUE(List<ECUE> lesECUE)
    {
       List<String> lesResultats = new ArrayList<String>();

        Iterator iter = lesECUE.iterator();

        while (iter.hasNext())
        {
            lesResultats.add(((ECUE)iter.next()).getNom());
        }

        return lesResultats;
    }     

    /**
    * Fonction qui retourne la liste des étudiants sous forme de chaînes de caractères
    * @param lesEtudiants : Liste des étudiants à convertir
    * @return Liste de dictionnaire. Les clés disponibles sont "unNom", "unPrenom" pour chaque étudiant
    */
    public List<Map> getLesEtudiants(List<Etudiant> lesEtudiants)
    {
       List<Map> lesResultats = new ArrayList<Map>();
       Map<String,String> uneLigne = null;
       Etudiant etudiantCourant = null;

       Iterator iter = lesEtudiants.iterator();

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           uneLigne = new HashMap<String,String>();

           //On ajoute couple nomAttribut/Valeur
           uneLigne.put("unNom", etudiantCourant.getNom());
           uneLigne.put("unPrenom", etudiantCourant.getPrenom());
           //On ajoute la ligne dans les résultats
           lesResultats.add(uneLigne);
       }

       return lesResultats;
    }
    /**
    * Fonction qui retourne la liste des étudiants sous forme de chaînes de caractères
    * @param lesEtudiants : Liste des étudiants à convertir
    * @param ecue : ECUE courante
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom" pour chaque étudiant. Si l'étudiant a une note, il y a aussi "uneNote","estRattrapage" (0 ou 1)
    */
     public List<Map> getLesEtudiantsECUE(List<Etudiant> lesEtudiants,ECUE ecue)
    {       
       List<Map> lesResultats = new ArrayList<Map>();
       Map<String,String> uneLigne = null;
       Etudiant etudiantCourant = null;
       Notation notationCourante = null;

       Iterator iter = lesEtudiants.iterator();

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           uneLigne = new HashMap<String,String>();

           //On ajoute couple nomAttribut/Valeur
           uneLigne.put("unNom", etudiantCourant.getNom());
           uneLigne.put("unPrenom", etudiantCourant.getPrenom());
        
           if( (notationCourante = etudiantCourant.getNoteECUE(ecue)) != null )
           {
                uneLigne.put("uneNote", Float.toString(notationCourante.getNote()));
                uneLigne.put("estRattrapage", trueFalse(notationCourante.isIsSecondSession()));
           }
           else
           {
              uneLigne.put("uneNote", "");
              uneLigne.put("estRattrapage", "");
           }
           //On ajoute la ligne dans les résultats
           lesResultats.add(uneLigne);
       }

       return lesResultats;
    }

    /**
    * Fonction qui retourne la liste des étudiants sous forme de chaînes de caractères
    * @param lesEtudiants : Liste des étudiants à convertir
    * @param ue : UE courante
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom" pour chaque étudiant. Puis le nom de chaque ECUE contenant comme valeur "sa note" suivi du caractère " R" s'il s'agit de sa note de rattrapage. Une dernière clé "estAPDJ" (0 ou 1) indique s'il a eu son UE par APDJ
    */
    public List<Map> getLesEtudiantsUE(List<Etudiant> lesEtudiants,UE ue)
    {
          //unNom|unPrenom|moyenneUE|NomECUE1|NomECUE2|estAPDJ
        //                          Note R | Note R
       List<Map> lesResultats = new ArrayList<Map>();
       Map<String,String> uneLigne = null;
       Etudiant etudiantCourant = null;
       Notation notationCourante = null;

       Iterator iter = lesEtudiants.iterator();
       Iterator iterECUE = null;
       ECUE ecueCourante = null;

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           uneLigne = new HashMap<String,String>();

           //On ajoute couple nomAttribut/Valeur
           uneLigne.put("unNom", etudiantCourant.getNom());
           uneLigne.put("unPrenom", etudiantCourant.getPrenom());
           uneLigne.put("moyenneUE", Float.toString(etudiantCourant.calculerMoyenneUE(ue)));

           iterECUE = etudiantCourant.getSesECUE().iterator();

           while (iterECUE.hasNext())
           {
                ecueCourante = (ECUE)iterECUE.next();
               if( (notationCourante = etudiantCourant.getNoteECUE(ecueCourante)) != null )
               {
                   if(notationCourante.isIsSecondSession())
                   {
                       uneLigne.put(ecueCourante.getNom(), Float.toString(notationCourante.getNote())+" R");
                   }
                   else
                   {
                       uneLigne.put(ecueCourante.getNom(), Float.toString(notationCourante.getNote()));
                   }
               }
           }

           uneLigne.put("estAPDJ", trueFalse(etudiantCourant.getLesAPDJ().contains(ue)));
           //On ajoute la ligne dans les résultats
           lesResultats.add(uneLigne);
       }

       return lesResultats;
    }

   /**
    * Fonction qui retourne la liste des étudiants du semestre courant sous forme de chaînes de caractères
    * @param lesEtudiants : Liste des étudiants à convertir
    * @param semestre  : Semestre courant
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom", "moyenneSemestre" pour chaque étudiant. La moyenne semestre contient sa moyenne / le nombre de point jury s'il en a. Chaque nom d'UE correspond à une clé ayant comme valeur "sa moyenne à l'UE" suivi du caractère " A" s'il a bénéficié d'APDJ. Une dernière clé "estEtranger" (0 ou 1) indique s'il a effectué son semestre à l'étranger
    */
    public List<Map> getLesEtudiantsSemestre(List<Etudiant> lesEtudiants,Semestre semestre)
    {
        //unNom|unPrenom|moyenneSemestre|    NomUE1  |   NomUE2   | estEtranger
        //            Moyenne/Point Jury| Moyenne A  | Moyenne A
       List<Map> lesResultats = new ArrayList<Map>();
       Map<String,String> uneLigne = null;
       Etudiant etudiantCourant = null;
       PointJury pt = null;
       Iterator iter = lesEtudiants.iterator();
       Iterator iterUE = null;
       UE ueCourante = null;

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           uneLigne = new HashMap<String,String>();

           //On ajoute couple nomAttribut/Valeur
           uneLigne.put("unNom", etudiantCourant.getNom());
           uneLigne.put("unPrenom", etudiantCourant.getPrenom());

           if((pt = etudiantCourant.getPointJurySemestre(semestre)) != null)
           {
              uneLigne.put("moyenneSemestre", Float.toString(etudiantCourant.calculerMoyenneSemestre(semestre))+"/"+Float.toString(pt.getNbPointJury()));
           }
           else
           {
                uneLigne.put("moyenneSemestre", Float.toString(etudiantCourant.calculerMoyenneSemestre(semestre)));
           }

           iterUE = etudiantCourant.getSesUE().iterator();

           while (iterUE.hasNext())
           {
                ueCourante = (UE)iterUE.next();
                if(etudiantCourant.getLesAPDJ().contains(ueCourante))
                {
                       uneLigne.put(ueCourante.getNom(), Float.toString(etudiantCourant.calculerMoyenneUE(ueCourante))+" A");
                }
                else
                {
                    uneLigne.put(ueCourante.getNom(), Float.toString(etudiantCourant.calculerMoyenneUE(ueCourante)));
                }               
           }

           uneLigne.put("estEtranger", trueFalse(etudiantCourant.isSemestreEtranger(semestre)));
           //On ajoute la ligne dans les résultats
           lesResultats.add(uneLigne);
       }

       return lesResultats;
    }

    /**
    * Fonction qui retourne la liste des étudiants de l'année courante sous forme de chaînes de caractères
    * @param lesEtudiants : Liste des étudiants à convertir
    * @param annee : année courante
    * @return Liste de dictionnaire de chaînes de caractères. Les clés disponibles sont "unNom", "unPrenom", "moyenneAnnuelle" pour chaque étudiant. La moyenne annuelle contient sa moyenne / le nombre de point jury s'il en a. Chaque numéro de semestre correspond à une clé ayant comme valeur "sa moyenne au semestre" /  le nombre de point jury s'il en a
    */
    public List<Map> getLesEtudiantsAnnee(List<Etudiant> lesEtudiants,Annee annee)
    {
        //unNom|unPrenom|moyenneAnnuelle| semestre1 | semestre2  |
        //                   moy/PJ     |moyenne/PJ | moyenne/PJ |
       List<Map> lesResultats = new ArrayList<Map>();
       Map<String,String> uneLigne = null;
       Etudiant etudiantCourant = null;
       PointJury pt = null;
       Iterator iter = lesEtudiants.iterator();
       Iterator iterSemestre = null;
       Semestre semestreCourant = null;

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           uneLigne = new HashMap<String,String>();

           //On ajoute couple nomAttribut/Valeur
           uneLigne.put("unNom", etudiantCourant.getNom());
           uneLigne.put("unPrenom", etudiantCourant.getPrenom());

           if((pt = etudiantCourant.getPointJuryAnnee(annee)) != null)
           {
                uneLigne.put("moyenneAnnuelle", Float.toString(etudiantCourant.calculerMoyenneAnnuelle())+"/"+Float.toString(pt.getNbPointJury()));
           }
           else
           {
                uneLigne.put("moyenneAnnuelle", Float.toString(etudiantCourant.calculerMoyenneAnnuelle()));
           }

           iterSemestre = etudiantCourant.getSesSemestres().iterator();

           while (iterSemestre.hasNext())
           {
               semestreCourant = (Semestre)iterSemestre.next();
               if((pt = etudiantCourant.getPointJurySemestre(semestreCourant)) != null)
               {
                    uneLigne.put(semestreCourant.getCodeApogee(), Float.toString(etudiantCourant.calculerMoyenneSemestre(semestreCourant))+"/"+Float.toString(pt.getNbPointJury()));
               }
               else
               {
                    uneLigne.put(semestreCourant.getCodeApogee(), Float.toString(etudiantCourant.calculerMoyenneSemestre(semestreCourant)));
               }
               
           }
           
           //On ajoute la ligne dans les résultats
           lesResultats.add(uneLigne);
       }

       return lesResultats;
    }

    /**
     * Fonction qui retourne les statistiques d'une ECUE sous forme de chaînes de caractères
     * @param lesEtudiants : Liste des étudiants à convertir
     * @param ecue : ECUE courante
     * @return Dictionnaire avec les clés : "nbEleve","nbNote","max","min","moyenne"
     */
    public Map getStatsECUE(List<Etudiant> lesEtudiants,ECUE ecue)
    {
       //nbEleve|nbNote|max|min|moyenne
       Map<String,String> lesResultats = new HashMap<String, String>();
       Etudiant etudiantCourant = null;
       Notation notationCourante = null;
       float max=0,min=20,cumul=0,moyenne = 0;
       int nbNote=0;
       
       lesResultats.put("nbEleve", Integer.toString(lesEtudiants.size()));

       Iterator iter = lesEtudiants.iterator();

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();

           if( (notationCourante = etudiantCourant.getNoteECUE(ecue)) != null )
           {
               cumul += notationCourante.getNote();

               if(notationCourante.getNote()>max)
                   max=notationCourante.getNote();

                if(notationCourante.getNote()<min)
                   min=notationCourante.getNote();

                nbNote++;
           }          
       }      
       
       lesResultats.put("nbNote", Integer.toString(nbNote));
       lesResultats.put("max", Float.toString(max));
       lesResultats.put("min", Float.toString(min));
       if(nbNote!=0)
         lesResultats.put("moyenne", Float.toString(cumul/nbNote));
       else
          lesResultats.put("moyenne", "0");

       return lesResultats;
    }

    /**
     * Fonction qui retourne les statistiques d'une UE sous forme de chaînes de caractères
     * @param lesEtudiants : Liste des étudiants à convertir
     * @param ue : UE courante
     * @return Dictionnaire avec les clés : "nbEleve","nbAPDJ","max","min","moyenne"
     */
    public Map getStatsUE(List<Etudiant> lesEtudiants,UE ue)
    {
       //nbEleve|moyenne|max|min|nbAPDJ
       Map<String,String> lesResultats = new HashMap<String, String>();
       Etudiant etudiantCourant = null;
       float max=0,min=20,cumul=0,moyenneCourante=0;;
       int nbAPDJ=0;

       lesResultats.put("nbEleve", Integer.toString(lesEtudiants.size()));

       Iterator iter = lesEtudiants.iterator();

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           moyenneCourante = etudiantCourant.calculerMoyenneUE(ue);

           cumul += moyenneCourante;

          if(moyenneCourante>max)
               max=moyenneCourante;

            if(moyenneCourante<min)
               min=moyenneCourante;

           if(etudiantCourant.getLesAPDJ().contains(ue))
               nbAPDJ++;
       }

       lesResultats.put("max", Float.toString(max));
       lesResultats.put("min", Float.toString(min));
       lesResultats.put("moyenne", Float.toString(cumul/lesEtudiants.size()));
       lesResultats.put("nbAPDJ", Float.toString(max));

       return lesResultats;
    }

   /**
     * Fonction qui retourne les statistiques d'un semestre sous forme de chaînes de caractères
     * @param lesEtudiants : Liste des étudiants à convertir
     * @param semestre  : Semestre courant
     * @return Dictionnaire avec les clés : "nbEleve","max","min","moyenne"
     */
    public Map getStatsSemestre(List<Etudiant> lesEtudiants,Semestre semestre)
    {
       //nbEleve|moyenne|max|min
       Map<String,String> lesResultats = new HashMap<String, String>();
       Etudiant etudiantCourant = null;
       float max=0,min=20,cumul=0,moyenneCourante=0;

       lesResultats.put("nbEleve", Integer.toString(lesEtudiants.size()));

       Iterator iter = lesEtudiants.iterator();

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           moyenneCourante = etudiantCourant.calculerMoyenneSemestre(semestre);

           cumul += moyenneCourante;

          if(moyenneCourante>max)
               max=moyenneCourante;

            if(moyenneCourante<min)
               min=moyenneCourante;
       }

       lesResultats.put("max", Float.toString(max));
       lesResultats.put("min", Float.toString(min));
       lesResultats.put("moyenne", Float.toString(cumul/lesEtudiants.size()));

       return lesResultats;
    }

     /**
     * Fonction qui retourne les statistiques d'une année sous forme de chaînes de caractères
     * @param lesEtudiants : Liste des étudiants à convertir
     * @return Dictionnaire avec les clés : "nbEleve","max","min","moyenne"
     */
    public Map getStatsAnnee(List<Etudiant> lesEtudiants)
    {
       //nbEleve|moyenne|max|min
       Map<String,String> lesResultats = new HashMap<String, String>();
       Etudiant etudiantCourant = null;
       float max=0,min=20,cumul=0,moyenneCourante=0;

       lesResultats.put("nbEleve", Integer.toString(lesEtudiants.size()));

       Iterator iter = lesEtudiants.iterator();

       while (iter.hasNext())
       {
           etudiantCourant = (Etudiant)iter.next();
           moyenneCourante = etudiantCourant.calculerMoyenneAnnuelle();

           cumul += moyenneCourante;

          if(moyenneCourante>max)
               max=moyenneCourante;

            if(moyenneCourante<min)
               min=moyenneCourante;
       }

       lesResultats.put("max", Float.toString(max));
       lesResultats.put("min", Float.toString(min));
       lesResultats.put("moyenne", Float.toString(cumul/lesEtudiants.size()));

       return lesResultats;
    }   

    /**
     * Fonction qui retourne sous forme de chaînes de caractères
     * @param bool
     * @return 1 si VRAI, 0 si FAUX
     */
    public String trueFalse(boolean bool)
    {
         if(bool)
             return "1";
         else
               return "0";
     }

    /**
     * Fonction qui retourne les majuscules du mot
     * @param mot
     * @return Chaîne de caractères contenant les majuscule du mot
     */
    public String getAbreviation(String mot)
    {
        String msg = "";
        for(int i=0;i<mot.length();i++)
        {
            if(mot.charAt(i) >= 'A' && mot.charAt(i) <= 'Z' && mot.charAt(i) != ' ')
                msg += mot.charAt(i);
        }

        return msg;

    }
}